package com.example.windswing;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.text.Editable;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.material.textfield.TextInputEditText;

import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;

public class MainActivity extends AppCompatActivity {
    private Handler handler = new Handler();
    private Button btnEnterCtrl;
    private Button btnConnect;

    private DatagramSocket socket = null;
    private WindSwingService windSwingService;

    //private InetAddress localAddress;
    private String localIP;

    private TextInputEditText ipInput;
    private TextInputEditText portInput;

    private Thread getLocalAddrThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ipInput = findViewById(R.id.ip_edit);
        portInput = findViewById(R.id.port_edit);

        btnEnterCtrl = findViewById(R.id.btn_enter_ctrl);
        btnEnterCtrl.setOnClickListener(this::onControlBtnClicked);

        ipInput.setText("192.168.0.");
        portInput.setText("9091");

        btnConnect = findViewById(R.id.btn_connect);
        btnConnect.setOnClickListener(view -> {
            if(windSwingService != null) {
                if(localIP == null){
                    new Thread(getLocalAddrThread).start();
                    return;
                }else if(windSwingService.getSocket() == null){
                    initService();
                }
                String data = "A" + localIP + ":9090";
                Editable ipEditable = ipInput.getEditableText();
                Editable portEditable = portInput.getEditableText();
                if(ipEditable == null || portEditable == null){
                    Toast.makeText(MainActivity.this, "请检查输入", Toast.LENGTH_SHORT).show();
                    return;
                }
                String windSwingIP = ipInput.getEditableText().toString();
                int windswingPort = Integer.parseInt(portInput.getEditableText().toString());
                new Thread(() -> {
                    windSwingService.setWindSwingAddress(windSwingIP, windswingPort);
                    windSwingService.sendData(data.getBytes(StandardCharsets.UTF_8));
                }).start();
            }else{
                Toast.makeText(MainActivity.this, "未绑定Service", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(this, WindSwingService.class);
                bindService(intent, serviceConnection, Service.BIND_AUTO_CREATE);
            }
        });

        getLocalAddrThread = new Thread(() -> {
            try {
                localIP = getIP();
                if (localIP == null){
                    runOnUiThread(() -> {
                        Toast.makeText(MainActivity.this, "未获取到\"192.168\"开头的IP", Toast.LENGTH_SHORT).show();
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        getLocalAddrThread.start();
    }

    private String getIP() throws SocketException {
        Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
        InetAddress ip;
        while (allNetInterfaces.hasMoreElements())
        {
            NetworkInterface netInterface = allNetInterfaces.nextElement();
            System.out.println(netInterface.getName());
            Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
            while (addresses.hasMoreElements())
            {
                ip = addresses.nextElement();
                if (ip instanceof Inet4Address) {
                    String ipstr = ip.getHostAddress();
                    if(ipstr != null && ipstr.contains("192.168")){
                        handler.post(() -> {
                            Toast.makeText(MainActivity.this, "获取到IP:"+ipstr, Toast.LENGTH_SHORT).show();
                        });
                        return ipstr;
                    }
                }
            }
        }
        return null;
        //todo 未完成
    }

    @Override
    protected void onStart() {
        super.onStart();
        Intent intent = new Intent(this, WindSwingService.class);
        bindService(intent, serviceConnection, Service.BIND_AUTO_CREATE);
    }

    public void onControlBtnClicked(View view){
        if(windSwingService != null) {
            if(windSwingService.getSocket() == null){
                Toast.makeText(MainActivity.this, "未连接到风力摆", Toast.LENGTH_SHORT).show();
                return;
            }
            startActivity(new Intent(this, CtrlActivity.class));
        }else{
            Toast.makeText(MainActivity.this, "未绑定Service", Toast.LENGTH_SHORT).show();
        }
    }

    private final WindSwingService.UDPRecv.OnReceivedListener onReceivedListener = (bytes, length) -> {
        String data = new String(bytes, StandardCharsets.UTF_8);
        if(data.charAt(0) == 'R') {
            String data2 = data.substring(1);
            windSwingService.toast("来自ESP32的应答：\n" + data2, Toast.LENGTH_SHORT);
        }
    };

    private void initService(){
        do {
            socket = windSwingService.createDatagramSocket(localIP);
        }while (socket == null);
        boolean threadCreated = windSwingService.createUDPThreads();
        Log.i("MY", "ThreadsCreated? " + threadCreated);
        windSwingService.setUdpRecvOnReceiveListener(onReceivedListener);
        windSwingService.startUDPRecvThreads();
    }


    private final ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            WindSwingService.ServiceBinder binder = (WindSwingService.ServiceBinder) iBinder;
            windSwingService = binder.getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            windSwingService = null;
        }
    };
}